/**
 * Copyright (c) 2016-2020 https://github.com/zhaohuatai
 *
 * contact 824069438@qq.com
 *  
 */
package org.zfes.snowy.auth.shiro.filter.sso;


import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.web.filter.PathMatchingFilter;
import org.apache.shiro.web.util.WebUtils;
import org.zfes.snowy.auth.AuthConsts;
import org.zfes.snowy.auth.shiro.util.SSOVerifyEncyptKeyUtil;
import org.zfes.snowy.core.util.Base58Util;
import org.zfes.snowy.core.util.UUIDUtil;
import org.zfes.snowy.core.util.ZStrUtil;
import org.zfes.snowy.core.util.encypt.AESUtil;
import org.zfes.snowy.core.util.encypt.RSAUtil;

/**
 *  /api/auth/sso/center/sync.so  <br>
 *  
 *  基本流程<br>
 *  var token =sessionid#uuid<br>
 *  RSA.sign(token)-->ssoSign<br>
 *  
 *  jsonp--callback data :{t_token:base64(AES(token))t_sign: base64(ssoSign)}<br>
 *  
 * @author zhaoht
 *
 */
public class SSOSyncCenterfilter extends PathMatchingFilter implements SSOSyncFilter{
	
	private List<String> allowedSSOClientDomains=java.util.Collections.emptyList();
	
	private String ssoCenterSyncPath=AuthConsts.SSO.ssoCenterSyncPath;
	
	
	@Override
	protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue)throws Exception {
		HttpServletRequest httpRequest=(HttpServletRequest) request ;
		HttpServletResponse httpResponse =(HttpServletResponse)response;
		PrintWriter out = httpResponse.getWriter();
		Session session = SecurityUtils.getSubject().getSession();
		if(pathsMatch(ssoCenterSyncPath,httpRequest)){
			
			if(!isAllowedDomain((HttpServletRequest) request )){
				out.println("error");//返回jsonp格式数据  
				session.stop();
				return false;
			}
			String aesPublicKey=SSOVerifyEncyptKeyUtil.readSSOAesPublicKey();
			//构造
			String ssoToken=(String) session.getId()+"#"+UUIDUtil.base58Uuid();
			String ssoSign=RSAUtil.sign(ssoToken.getBytes(), SSOVerifyEncyptKeyUtil.readSSOSignPrivateKey());
			// aes 加密
			ssoToken = AESUtil.encrypt(ssoToken, aesPublicKey);
			ssoSign= AESUtil.encrypt(ssoSign, aesPublicKey);
			// base58编码
			ssoToken=Base58Util.encodeToBase58(ssoToken);
			ssoSign=Base58Util.encodeToBase58(ssoSign);
			System.out.println("SSOSyncCenterfilter-sessionid|| "+session.getId());
			//发送数据
		 	String callback = WebUtils.getCleanParam(request, "jsonpCallback"); 
		 	callback=ZStrUtil.hasNoText(callback)?"jsonpCallback":callback;
		 	//CookieUtil.setSessionCookie(WebUtils.toHttp(response),AuthConsts.COOKIES.authSid, session.getId().toString(),"/",true);
		 	//CookieUtil.setSessionCookie(WebUtils.toHttp(response),AuthConsts.COOKIES.authSid, session.getId().toString(),"127.0.0.1","/",true) ;
		 	out.println(callback+"({\""+AuthConsts.SSO.ssoTokenParam+"\":\""+ssoToken+"\",\""+AuthConsts.SSO.ssoSignParam+"\":\""+ssoSign+"\"})");//返回jsonp格式数据  
		 	out.flush();  
		    out.close();
			return false;
		}
	    return true;
	}
	
	private boolean isAllowedDomain(HttpServletRequest request ){
		String referer=request.getHeader("referer");
		if(ZStrUtil.hasNoText(referer)){
			return false;
		}
		boolean isAllowed=allowedSSOClientDomains.stream().anyMatch(val-> referer.startsWith(val));
		return isAllowed;
	}





	public List<String> getAllowedSSOClientDomains() {
		return allowedSSOClientDomains;
	}

	public void setAllowedSSOClientDomains(List<String> allowedSSOClientDomains) {
		this.allowedSSOClientDomains = allowedSSOClientDomains;
	}

	public String getSsoCenterSyncPath() {
		return ssoCenterSyncPath;
	}

	public void setSsoCenterSyncPath(String ssoCenterSyncPath) {
		this.ssoCenterSyncPath = ssoCenterSyncPath;
	}
}
